package com.lg.startertemplate.dao.impl;


import com.lg.startertemplate.dao.DaoBase;
import com.lg.startertemplate.domain.TUser;
import com.lg.startertemplate.povo.UserRes;
import com.lg.startertemplate.povo.UserResp;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;

@Repository
public interface UserDao extends DaoBase<TUser, Long> {


    //根据id查唯一的一条  不存在时为null
    TUser findAllById(Long id);


    /**
     * 根据方法名查询
     */
//    多字段 模糊查询 且 多字段排序 分页
    Page<TUser> findByNameLikeAndGridSetLikeOrderByIdDescNameAsc(String name, String set, Pageable pageable);

    //    多字段 模糊查询 或 多字段排序 分页
    Page<TUser> findByNameLikeOrGridSetLikeOrderByIdDescNameAsc(String name, String set, Pageable pageable);


    /**
     * 各关键子使用
     */
//    between  英文可以(则其他英文也是支持的)    左闭右闭
    List<TUser> findByNameBetween(String sName, String nName);

    List<TUser> findByAgeBetween(Integer sName, Integer nName);


    //    小于  大于等于 ...
    List<TUser> findByAgeLessThan(Integer num);

    List<TUser> findByAgeGreaterThanEqual(Integer num);

    //不等于
    List<TUser> findByAgeNot(Integer num);

    //   所以 所有的关键字都可以加 not
    List<TUser> findByNameNotLike(String sName);

    //    name is null
    List<TUser> findByNameIsNull();

    //    name is not null
    List<TUser> findByNameIsNotNull();

    //    name = fale
    List<TUser> findByIdentifyFalse();

    //    name=true
    List<TUser> findByIdentifyTrue();

    //    UPPER(name) = UPPER(?1)
    List<TUser> findByNameIgnoreCase(String sName);

    //    模糊查询  Top关键字可以加在任意的点  自定义返回
    List<TUser> findTop2ByNameLike(String sName);

    List<TUser> findByNameLike(String sName);

    List<UserResp> findByNameStartingWith(String sName);

    List<UserRes> findByNameEndingWith(String sName);

    List<TUser> findByNameContaining(String sName);

    //自定义返回
    @Query(value = "select age,name from t_user", nativeQuery = true)
    List<Map<String, Object>> queryBySome();


    /**
     * @query nativeQuery = true
     * 原生query 对于排序 分页等正吃的不是很友好,需要自己在sql中 用做
     * <p>
     * 需要排序 分页等 最好用 nativeQuery=false(默认)
     */
    @Query(value = "select * from t_user limit :limitn  offset :offsetn ", nativeQuery = true)
    List<TUser> querySomeByMyself(@Param("limitn") Integer limtNum, @Param("offsetn") Integer offsetNum);

    //new 不能用page接
    @Query(value = "select new com.lg.startertemplate.domain.TUser(id, createTime, updateTime, age, name, identify) from t_user  where  name like %?1")
    List<TUser> querySome(String name, Pageable pageable);
    //返回 user类型
    @Query(value = "select u from t_user u where  u.name like %?1")
    Page<TUser> querySome2(String name, Pageable pageable);


    //------不推荐 下面两种------
    //返回 string类型
    @Query(value = "select u.name from t_user u where  u.name like %?1")
    Page<TUser> querySome3(String name, Pageable pageable);
    //返回 object类型
    @Query(value = "select u.name,u.age from t_user u where  u.name like %?1")
    Page<TUser> querySome4(String name, Pageable pageable);
//    启动报错
//    @Query(value = "select name,age from t_user  where  name like %?1")
//    Page<TUser> querySome5(String name, Pageable pageable);


//    jpa查询
//    t_user 可以直接换成类名 如果那边没有写 (name = "t_user")
    @Query("SELECT new com.lg.startertemplate.domain.TUser(sum(age),max(age)) from t_user GROUP BY name ORDER BY sum(age) desc")
    List<TUser> sumAgeByName();

//    因为它是jpa 所以直接可以用其自己的分页 直接传参就可以 (Pageable / PageRequest)
    @Query("SELECT DISTINCT name FROM t_user")
    Set<String> distinctName();

    @Query("SELECT new com.lg.startertemplate.domain.TUser(name,age) from t_user WHERE id in ?1")
    List<TUser> queryInSome(List<Long> ids);


//------------------------------------分解线 上面是查询--------------------------------------

    /**
     * 修改必须加事务
     *
     *  返回  1正常 0异常
     * @param name
     * @param user_id
     * @return
     */
    @Modifying
    @Transactional
    @Query(value = "update t_user set name = :na where id = :id", nativeQuery = true)
    Integer updateSomeThing(@Param("na") String name, @Param("id") Integer user_id);


    /**
     *
     * 改    内部 save  /  上面
     * 查    上面
     *
     * 曾    内部 save
     * 删    内部 delete
     *
     *
     *
     *
     *
     * 可以调用已经创建的 存储过程, 如有需求,后期查找丰富
     *
     *
     *
     *
     *
     * 表的操作 创建表  查表是否存在 修改表名/字段 删除表
     * 使用jdbc封装
     *
     * 库的操作 创建一个数据库 查看这个数据库是否存在  修改数据库的名字   删除这个数据库
     * java调c
     */



    /**
     * 创建数据库
     * <p>
     * 无法动态传参
     *
     * @param tableName
     */
    @Transactional
    @Query(value = "CREATE TABLE 00_table (id SERIAL primary key ,create_time timestamp(6),update_time timestamp(6),test_col varchar(255));", nativeQuery = true)
    @Modifying
    void createTable(String tableName);


}
